/**
 * 接受udp广播，寻找房间
 */
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include "tinycthread.h"
#include "network.h"
#include "procedure.h"

#pragma comment(lib, "ws2_32.lib")

bool udpRecOn = false;
extern int foundRoomCount;
SOCKET udpRecSocket;
//Todo: 房间列表管理
int asyncRec(void *arg)
{
    struct sockaddr_in clientAddr{};
    int clientAddrLen = sizeof(clientAddr);
    char buffer[1024];
    while (udpRecOn) {
        // 检查套接字是否有数据可供接收
        fd_set readSet;
        FD_ZERO(&readSet);
        FD_SET(udpRecSocket, &readSet);
        struct timeval timeout{};
        timeout.tv_sec = 0;
        timeout.tv_usec = 1000; // 设置等待时间为1000微秒，即1毫秒
        int selectResult = select(0, &readSet, NULL, NULL, &timeout);
        if (selectResult == SOCKET_ERROR) {
            printf("Failed to check socket for incoming data\n");
            closesocket(udpRecSocket);
            return false;
        }

        // 如果套接字有数据可供接收
        if (selectResult > 0) {
            // 接收广播消息
            if (recvfrom(udpRecSocket, buffer, 1024, 0, (struct sockaddr*)&clientAddr, &clientAddrLen) == SOCKET_ERROR) {
                printf("Failed to receive broadcast message\n");
                closesocket(udpRecSocket);
                return false;
            }
            char *p = buffer;
            char *RoomInfo = new char[64];
            memset(RoomInfo,0,64);
            for (int i = 0; i < 1024; ++i) {
                if (buffer[i] == '<' && buffer[i+1] == '[') {
                    for (int j = i+2; j < 1024; ++j) {
                        if(buffer[j] == ']' && buffer[j+1] == '>') {
                            buffer[j] = 0;
                            strcpy(RoomInfo,&buffer[i+2]);
                        }
                    }
                }
            }

            AddRemoteRoom(RoomInfo, inet_ntoa(clientAddr.sin_addr));
        }
        // 如果等待超时，继续下一次循环
    }
    closesocket(udpRecSocket);
    printf("已停止寻找房间\n");
    return 0;
}

bool StartFindRoom() {
    
    struct sockaddr_in serverAddr;

    // 创建UDP socket
    if ((udpRecSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
        printf("Failed to create socket\n");
        return false;
    }
    
    // 将套接字设置为非阻塞模式
    u_long nonBlocking = 1;
    if (ioctlsocket(udpRecSocket, FIONBIO, &nonBlocking) == SOCKET_ERROR) {
        printf("Failed to set socket to non-blocking mode\n");
        closesocket(udpRecSocket);
        return false;
    }

    // 构建本地地址
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(PORT);

    // 绑定socket到本地地址
    if (bind(udpRecSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        printf("Failed to bind socket\n");
        closesocket(udpRecSocket);
        return false;
    }

    udpRecOn = true;
    thrd_t recer;
    thrd_create(&recer,asyncRec,NULL);
    return true;
}

void StopReceiveUdp()
{
    udpRecOn = false;
}